package com.ustadzmenjawab.client;

import gwtspeechbubble.client.SpeechBubble;

import java.util.ArrayList;
import java.util.List;


import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SuggestOracle;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
//import com.reveregroup.gwt.facebook4gwt.Facebook;
//import com.reveregroup.gwt.facebook4gwt.ShareButton;
import com.ustadzmenjawab.client.images.WebImages;
import com.ustadzmenjawab.shared.Constant;
import com.ustadzmenjawab.shared.SearchResult;

public class SearchResultPage extends Composite{
	protected static final String LEFT_PANEL_WIDTH = "180px";
	protected TextBox searchBox;
	protected SuggestOracle suggestoracle;
	protected Button searchButton;
	protected TextBox bottomSearchBox;
	protected Button bottomButton;
	protected FlexTable horizontal ;
	protected FlexTable bottomSearch ;
	protected VerticalPanel leftPanel ;
	protected VerticalPanel centralPanel;
	protected HorizontalPanel spellSuggestPanel;
	protected Panel resultPanel;
	protected Panel pagingPanel;
	protected Panel panel;
	protected DockPanel basePanel;
	protected Panel topPanel;
	protected SpeechBubble speechBubble;

	protected int scrWidthResolution ;
	protected int scrHeightResolution ;
//	protected ShareButton fbShare;
	protected PreviewCallBack previewCallBack = new PreviewCallBack();
	
	protected HTML aboutUsLink ;
	protected HTML copyrightMark;
	protected Panel southPanel;
	
	private  AsyncCallback callback = new AsyncCallback(){
		@Override
		public void onFailure(Throwable caught) {
			showErrorDialog("Mohon maaf, terdapat masalah teknis dalam pencarian.");
		}

		@Override
		public void onSuccess(Object result) {
			ArrayList<SearchResult> rs  = (ArrayList<SearchResult>)result;

			reloadCentralPanel(rs);
		}
	};
    
	private  AsyncCallback spellSuggestCallback = new AsyncCallback(){
		@Override
		public void onFailure(Throwable caught) {
			showErrorDialog("Mohon maaf, terdapat masalah teknis dalam pencarian.");
		}

		@Override
		public void onSuccess(Object result) {
			String rs  = (String)result;

			insertSpellSuggestion(rs);
		}
	};
	
	private  AsyncCallback countCallBack = new AsyncCallback(){

		@Override
		public void onFailure(Throwable caught) {
			showErrorDialog("Mohon maaf, terdapat masalah teknis dalam pencarian.");
		}

		@Override
		public void onSuccess(Object result) {
			Integer cnt = (Integer)result;
			if(cnt > Constant.MAX_HIT_NUM)
				cnt = Constant.MAX_HIT_NUM;
			updatePagingPanel(cnt, "sourceName",null);
		}
	};

	class SimilarCountCallback implements AsyncCallback{
		private int qid;

		public SimilarCountCallback(int questionid){
			qid = questionid;
		}
		@Override
		public void onFailure(Throwable caught) {
			showErrorDialog("Mohon maaf, terdapat masalah teknis dalam pencarian.");
		}
		@Override
		public void onSuccess(Object result) {
			Integer cnt = (Integer)result;
			if(cnt > Constant.MAX_HIT_NUM)
				cnt = Constant.MAX_HIT_NUM;
			updatePagingPanel(cnt, "questionid",""+qid);
		}
	};

	private  AsyncCallback sourceLsCallBack = new AsyncCallback(){
		@Override
		public void onFailure(Throwable caught) {
			showErrorDialog("Mohon maaf, terdapat masalah teknis dalam pencarian.");

		}
		@Override
		public void onSuccess(Object result) {
			ArrayList<String> rs  = (ArrayList<String>)result;
			updateLeftPanel(rs);

		}
	};

	class SourceCountCallback  implements AsyncCallback{
		private String sourceName;

		public SourceCountCallback(String source){
			this.sourceName = source;
		}
		public void onFailure(Throwable caught) {
			showErrorDialog("Mohon maaf, terdapat masalah teknis dalam pencarian.");

		}

		@Override
		public void onSuccess(Object result) {
			Integer cnt = (Integer)result;
			if(cnt > Constant.MAX_HIT_NUM)
				cnt = Constant.MAX_HIT_NUM;
			updatePagingPanel(cnt, "sourceName",sourceName);
		}
	};

	private AsyncCallback pageVisitCallBack = new AsyncCallback(){

		@Override
		public void onFailure(Throwable caught) {	
		}
		@Override
		public void onSuccess(Object result) {			
		}
	};

	private AsyncCallback similarQuestionCallBack = new AsyncCallback(){
		@Override
		public void onFailure(Throwable caught) {
			showErrorDialog("Mohon maaf, terdapat masalah teknis dalam pencarian.");
		}

		@Override
		public void onSuccess(Object result) {
			ArrayList<SearchResult> rs  = (ArrayList<SearchResult>)result;
			reloadCentralPanel(rs);
		}
	};

	private AsyncCallback similarQuestionPagingCallBack = new AsyncCallback(){
		@Override
		public void onFailure(Throwable caught) {
			showErrorDialog("Mohon maaf, terdapat masalah teknis dalam pencarian.");
		}

		@Override
		public void onSuccess(Object result) {
			ArrayList<SearchResult> rs  = (ArrayList<SearchResult>)result;
			reloadCentralPanel(rs);
		}
	};

	class  PreviewCallBack implements AsyncCallback{
		int posX;
		int posY;


		@Override
		public void onFailure(Throwable caught) {
			showErrorDialog("Mohon maaf, terdapat masalah teknis dalam pencarian.");

		}
		@Override
		public void onSuccess(Object result) {
			String question = (String) result;
			if(speechBubble != null){
				speechBubble.setVisible(false);
				centralPanel.remove(speechBubble);
			}
			speechBubble = new SpeechBubble();
			Label qLabel = new Label(question);
			qLabel.setWidth(""+scrWidthResolution/4+"px");
			qLabel.setWordWrap(true);

			speechBubble.with(qLabel);
			centralPanel.add(speechBubble);
			speechBubble.moveTo(resultPanel.getOffsetWidth(), posY - centralPanel.getAbsoluteTop() + (3 * speechBubble.getOffsetHeight()/4));
			speechBubble.setVisible(true);
		}

		public void setPosX(int x){
			posX = x;
		}

		public void setPosY(int y){
			posY = y;
		}
	};
	class SearchButtonHandler implements ClickHandler{

		@Override
		public void onClick(ClickEvent event) {
			Button button = (Button)event.getSource();
			String searchKeyword ="";
			if(button == searchButton){
				searchKeyword = searchBox.getText();
				startSearching(searchBox.getText());
			}else if(button == bottomButton){
				searchKeyword = bottomSearchBox.getText();
				startSearching(searchKeyword);
			}
			History.newItem("search&amp;"+searchKeyword);
		}

	}
	class SearchValueChangeHandler implements ValueChangeHandler<String>{

		@Override
		public void onValueChange(ValueChangeEvent<String> event) {
			handleHistoryToken(event.getValue());
		}

		public void handleHistoryToken(String token){
			String historyToken = token;
			try {
				String[] tokens = historyToken.split("&amp;");
				setCentralPanelLoading();
				AppControlServiceAsync appService = getAppControlService();
				if(tokens[0].equalsIgnoreCase("search")){

					basePanel.remove(topPanel);
					basePanel.add(panel, DockPanel.CENTER);
					basePanel.add(topPanel,DockPanel.NORTH);
					searchBox.setText(tokens[1]);
					hideSpeechBubble();
					if(bottomSearchBox != null)
						bottomSearchBox.setText(tokens[1]);
					setCentralPanelLoading();
					updateLeftPanel(null);
					String keyword = verifyKeyword(tokens[1]);
					if(tokens.length == 4){
						String sourceName = tokens[2];
						int start = Integer.parseInt(tokens[3]);
						appService.searchKeyword(keyword,sourceName, start, Constant.HIT_PER_PAGE, callback);
					}else if(tokens.length == 3){
						int start = Integer.parseInt(tokens[2]);
						appService.searchKeyword(keyword, start, Constant.HIT_PER_PAGE, callback);
					}else if(tokens[1] != null){
						//startSearching(keyword);
						appService.getSpellSuggestion(keyword, spellSuggestCallback);
						appService.searchKeyword(keyword, callback);
						
					}
					appService.getTotalCount(keyword, countCallBack);
					appService.getSourcesForResult(keyword, sourceLsCallBack);
				}else if(tokens[0].equalsIgnoreCase("searchSimilar")){
					if(tokens.length == 4){
						String keyword = tokens[1];
						int qid = Integer.parseInt(tokens[2]);
						int start = Integer.parseInt(tokens[3]);
						appService.searchSimilarQuestion(keyword, qid, start, Constant.HIT_PER_PAGE, similarQuestionPagingCallBack);
					}else if(tokens[1] != null && tokens.length == 3){
						String keyword = tokens[1];
						int questionId = Integer.parseInt(tokens[2]);
						appService.searchSimilarQuestion(keyword, questionId, similarQuestionCallBack);
						SimilarCountCallback simCountCallback = new SimilarCountCallback(questionId);
						appService.getCountSimilarResult(questionId, simCountCallback);
					}		
				}
			}catch (IndexOutOfBoundsException e) {

			}

		}
	}
	class KeyButtonHandler implements KeyDownHandler{

		@Override
		public void onKeyDown(KeyDownEvent event) {
			if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
				TextBox box = (TextBox)event.getSource();
				startSearching(box.getText());
				History.newItem("search&amp;"+box.getText());

			}
		}

	}
	class SimilarQuestionHandler implements ClickHandler{
		String keyword;
		int questionId ;
		public SimilarQuestionHandler(String keyword, int qid){
			questionId = qid;
			this.keyword = keyword;
		}
		@Override
		public void onClick(ClickEvent event) {
			setCentralPanelLoading();
			AppControlServiceAsync appService = getAppControlService();
			appService.searchSimilarQuestion(keyword, questionId, similarQuestionCallBack);
			SimilarCountCallback simCountCallback = new SimilarCountCallback(questionId);
			appService.getCountSimilarResult(questionId, simCountCallback);
			History.newItem("searchSimilar&amp;"+keyword+"&amp;"+questionId);
		}
	}
	class PageClickHandler implements ClickHandler{
		String url;

		public PageClickHandler(String url){
			this.url = url;
		}
		@Override
		public void onClick(ClickEvent event) {
			if(url != null){
				AppControlServiceAsync appService = getAppControlService();
				if(url.toLowerCase().contains("www.dar-alifta.org")){
					Window.open(url, "dar-alifta", "");
					Window.open("http://www.dar-alifta.org/ChangeLang.aspx?LangID=5", "dar-alifta", "");
				}
				
				appService.updateVisit(url,  pageVisitCallBack);
	
			}
		}

	}

	class PreviewClickHandler implements  ClickHandler, MouseOutHandler{
		int pageId;
		boolean active ;

		public PreviewClickHandler(int id){
			this.pageId = id;
			this.active = false;
		}

		@Override
		public void onMouseOut(MouseOutEvent event) {
			hideSpeechBubble();
			active = false;
		}

		@Override
		public void onClick(ClickEvent event) {
			if(!active){
				AppControlServiceAsync appService = getAppControlService();
				ImageAnchor source = (ImageAnchor)event.getSource();
				int x = source.getAbsoluteLeft();

				int y = source.getAbsoluteTop();
				previewCallBack.setPosX(x);
				previewCallBack.setPosY(y);
				appService.getQuestion(pageId, previewCallBack);
				active = true;
			}else{
				hideSpeechBubble();
				active = false;
			}
		}


	}
	
	class AboutUsLinkHandler implements ClickHandler{

		@Override
		public void onClick(ClickEvent event) {
			AboutUsPage aboutUs = new AboutUsPage();
			basePanel.clear();
			basePanel.add(aboutUs,DockPanel.CENTER);
		
		}
		
	}
	
	public SearchResultPage(){

	}
	public SearchResultPage(String keyword,String[] sources, SearchResult[] msg){
		WebImages webImage = (WebImages) GWT.create(WebImages.class);
		scrWidthResolution = getScreenWidth();
		scrHeightResolution = getScreenHeight();
		Image logo = null;
		basePanel= new DockPanel();
		searchButton = new Button("Cari");
		searchBox = new TextBox();

		leftPanel = new VerticalPanel();
		centralPanel = new VerticalPanel() ;
		if(scrWidthResolution >= 768){
			//for PC
			if(scrWidthResolution >= 1200){
				logo = webImage.ustadzmenjawab_1280().createImage();
			}else if(scrWidthResolution >= 1000){
				logo = webImage.ustadzmenjawab_1024().createImage();
			}else if(scrWidthResolution >= 768){
				logo = webImage.ustadzmenjawab_800().createImage();
			}
			logo.addClickHandler(new LogoClickHandler());
			int logoWidth = scrWidthResolution/3;
			searchBox.setWidth((scrWidthResolution * 1 /3) +"px");
			searchBox.setStyleName("search-box");
			searchButton.setPixelSize(80, 25);
			topPanel = new DockPanel();
			DockPanel top = (DockPanel) topPanel;
			top.add(logo,DockPanel.WEST);
			horizontal = new FlexTable();
			horizontal.setWidget(0, 0, searchBox);
			horizontal.setWidget(0, 1, searchButton);
			top.add(horizontal,DockPanel.CENTER);
			top.setCellVerticalAlignment(horizontal, VerticalPanel.ALIGN_MIDDLE);
			aboutUsLink = new HTML ("<a style=\"text-decoration: none;\" onmouseover =\"this.style.textDecoration = 'underline';\" onmouseout=\"this.style.textDecoration= 'none';\" href=\"#\"><font color=\"#7fbce8\">Tentang Kami</font></a>");
			copyrightMark = new HTML("<font color=\"#7fbce8\">&copy; Ustadz Menjawab 2012</font>");
			aboutUsLink.addClickHandler(new AboutUsLinkHandler());
		//	Facebook.init("47869f3b2a492b1c3d8a47cc8bb92084");
		//	fbShare = new ShareButton("http://www.ustadzmenjawab.com","Mesin pencari tanya-jawab syariah islam");
			panel = new DockPanel();
			DockPanel dPanel = (DockPanel) panel;
			dPanel.add(leftPanel, DockPanel.WEST);
			dPanel.setCellWidth(leftPanel, LEFT_PANEL_WIDTH);
			dPanel.add(centralPanel,DockPanel.CENTER);
			southPanel = new HorizontalPanel();
			southPanel.setStyleName("footer");
			southPanel.add(copyrightMark);
			southPanel.add(new HTML("<font color=\"#7fbce8\">&nbsp;|&nbsp;</font>") );
			southPanel.add(aboutUsLink);
			southPanel.add(new HTML("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;") );
			basePanel.add(southPanel,DockPanel.SOUTH);
			basePanel.setCellHorizontalAlignment(southPanel, DockPanel.ALIGN_CENTER);
		}
		panel.setWidth("100%");
		searchBox.addKeyDownHandler(new KeyButtonHandler());
		basePanel.setStyleName("base-Panel");


		if(keyword != null && keyword.length() > 0)
			searchBox.setText(keyword);
		updateCentralPanel(msg);
		if(sources != null){
			for(String source:sources){
				leftPanel.add(new Hyperlink(source,true,source));
			}
		}


		basePanel.add(topPanel, DockPanel.NORTH);
		basePanel.setCellHeight(topPanel, (Window.getClientHeight() - 30)+"px");
		basePanel.setCellWidth(topPanel, Window.getClientWidth()+"px");
		basePanel.setCellHorizontalAlignment(topPanel, DockPanel.ALIGN_CENTER);
		basePanel.setCellVerticalAlignment(topPanel, DockPanel.ALIGN_MIDDLE);

		searchButton.addClickHandler(new SearchButtonHandler());
		SearchValueChangeHandler historyHandler  = new SearchValueChangeHandler();
		History.addValueChangeHandler(historyHandler);
		Window.enableScrolling(false);
		initWidget(basePanel);
		String token = History.getToken();
		if(token.length() > 0){
			historyHandler.handleHistoryToken(token);
		}
	}
	public void hideSpeechBubble(){
		if(speechBubble != null && speechBubble.isVisible())
			speechBubble.setVisible(false);
	}

	public void startSearching(String searchKeyword){
		basePanel.remove(topPanel);
		basePanel.add(panel, DockPanel.CENTER);
		basePanel.add(topPanel,DockPanel.NORTH);
		searchBox.setText(searchKeyword);
		hideSpeechBubble();
		if(bottomSearchBox != null)
			bottomSearchBox.setText(searchKeyword);
		setCentralPanelLoading();
		updateLeftPanel(null);
		AppControlServiceAsync appService = getAppControlService();
		String keyword = verifyKeyword(searchKeyword);
		appService.searchKeyword(keyword, callback);
		appService.getTotalCount(keyword, countCallBack);
		appService.getSourcesForResult(keyword, sourceLsCallBack);
		appService.getSpellSuggestion(keyword, spellSuggestCallback);
	}


	public AppControlServiceAsync getAppControlService(){
		AppControlServiceAsync appService = GWT.create(AppControlService.class);
		ServiceDefTarget endpoint = (ServiceDefTarget) appService;
		String moduleRelativeURL = GWT.getModuleBaseURL() + "appcontrol";
		endpoint.setServiceEntryPoint(moduleRelativeURL);

		return appService;
	}

	private String verifyKeyword(String text){
		boolean accepted = true;
		if(text == null)
			accepted  = false;
		text = text.trim();
		if( text.length() == 0)
			accepted  = false;
		String txt_low = text.toLowerCase();
		if(txt_low.contains("delete") || txt_low.contains("drop table") || txt_low.contains("truncate"))
			accepted  = false;
		if(accepted)
			return text;
		searchBox.setText("");
		Window.alert("Kata pencarian tidak diterima.");
		return null;
	}
	public void reloadCentralPanel(List<SearchResult> rs){
		centralPanel.remove(resultPanel);
		if(rs != null)
			updateCentralPanel(rs.toArray(new SearchResult[rs.size()]));
		else{
			resultPanel = new VerticalPanel();
			resultPanel.add(new HTML("<font color=\"red\">Hasil pencarian tidak ditemukan</font>"));
			centralPanel.add(resultPanel);
		}
	}
	
	public void insertSpellSuggestion(String spellSuggest){
		if(spellSuggestPanel != null)
			centralPanel.remove(spellSuggestPanel);
		if(spellSuggest == null)
			return;
		spellSuggestPanel = new HorizontalPanel();
		Label didyoumean = new Label("Maksud anda:   ");
		didyoumean.setStyleName("didYouMeanLabel");
		spellSuggestPanel.add(didyoumean);
		Hyperlink searchsuggest = new Hyperlink(spellSuggest,true,"search&amp;"+spellSuggest);
		searchsuggest.setStyleName("result-title");
		spellSuggestPanel.add(searchsuggest);
		spellSuggestPanel.setStyleName("didYouMean");
		centralPanel.insert(spellSuggestPanel, 0);
	}

	public int getResultLsWidth(){
		return scrWidthResolution/2;
	}
	private VerticalPanel convertToHTML(SearchResult[] result){
		if(result == null)
			return null;
		//StringBuffer buf = new StringBuffer();
		int c = 0;
		VerticalPanel centralLs = new VerticalPanel();
		HorizontalPanel titlePanel = null;
		HorizontalPanel featurePanel = null;
		//centralLs.setWidth("900px");
		centralLs.setWidth(getResultLsWidth()+"px");
		for(SearchResult s : result)
		{
			c++;
			String upTitle = s.getTitle().substring(0,1).toUpperCase() + s.getTitle().substring(1).toLowerCase();
			String url = s.getUrl();
			String url_lower = url.toLowerCase();
			titlePanel = new HorizontalPanel();
			featurePanel = new HorizontalPanel();
			if(url_lower.endsWith(".pdf"))
				upTitle = "[PDF] "+ upTitle;
			else if (url_lower.endsWith(".rtf"))
				upTitle = "[RTF] "+ upTitle;
			else if (url_lower.endsWith(".doc"))
				upTitle = "[DOC] "+ upTitle;
			String offline = s.getOffline();

			Anchor a = new Anchor(upTitle,true,s.getUrl());
			a.setStyleName("result-title");
		
			if(offline.equalsIgnoreCase("Y")){
				a.setHref("http://www.google.com/search?q=cache:"+s.getUrl());
			}else if(offline.equalsIgnoreCase("T")){
				a.setHref("http://www.google.com/search?q=cache:"+s.getUrl()+"&strip=1");
			}
			a.setWordWrap(true);

			//centralLs.add(new HTML("<a href=\""+s.getUrl()+"\">"+upTitle+"</a>"));
			ImageAnchor preview = new ImageAnchor();
			preview.setResource(Resources.INSTANCE.preview());
			PreviewClickHandler prevHandler = new PreviewClickHandler(s.getId());
			preview.addClickHandler(prevHandler);
			preview.addMouseOutHandler(prevHandler);
			titlePanel.add(a);
			titlePanel.add(new HTML("&nbsp;&nbsp"));
			titlePanel.add(preview);
			centralLs.add(titlePanel);


			a.addClickHandler(new PageClickHandler(url));
		
			HTML similar = new HTML("<a style=\"text-decoration: none;\" onmouseover=\"this.style.textDecoration = 'underline'\" onmouseout=\"this.style.textDecoration = 'none'\" href=\"#\"><font color=\"#7fbce8\">Masalah Serupa</font></a>");
			SimilarQuestionHandler simqhandler = new SimilarQuestionHandler(searchBox.getText(),s.getId());
			similar.addClickHandler(simqhandler);
			similar.setStyleName("result-feature");
			HTML summary = new HTML();
			summary.setWordWrap(true);
			summary.setWidth(getResultLsWidth()+"px");
			summary.setHTML(processSummary(s.getSummary()));

			centralLs.add(summary);
			featurePanel.add(new HTML("<font color=\"green\">"+processSource(s)+"</font>"));
			if(url_lower.endsWith(".pdf") || url_lower.endsWith(".rtf")|| url_lower.endsWith(".doc") || url_lower.endsWith(".docx")){
				if(!url_lower.endsWith(".rtf") ){
					featurePanel.add(new HTML("&nbsp;-&nbsp;<a style=\"text-decoration: none;\" onmouseover=\"this.style.textDecoration = 'underline'\" onmouseout=\"this.style.textDecoration = 'none'\" href=\"http://docs.google.com/gview?url="+url+ "\"><font color=\"#7fbce8\">Tampilkan Segera</font></a>"));
				}
			}
			//			else{
			//				featurePanel.add(new HTML("&nbsp;-&nbsp;<a style=\"text-decoration: none;\" onmouseover=\"this.style.textDecoration = 'underline'\" onmouseout=\"this.style.textDecoration = 'none'\" href=\"http://www.google.com/search?q=cache:"+url+ "\"><font color=\"#7fbce8\">Arsip</font></a>"));
			//				//centralLs.add(new HTML("<font color=\"green\">"+s.getUstadz()+"</font>&nbsp;-&nbsp;<a style=\"text-decoration: none;\" onmouseover=\"this.style.textDecoration = 'underline'\" onmouseout=\"this.style.textDecoration = 'none'\" href=\"http://www.google.com/search?q=cache:"+url+ "\"><font color=\"#7fbce8\">Arsip</font></a>"));
			//			}

			if(isSimilarSearchEnabled()){
				featurePanel.add(new HTML("&nbsp;-&nbsp;"));
				featurePanel.add(similar);
			}
			centralLs.add(featurePanel);
			centralLs.add(new HTML("&nbsp;"));
		}
		return centralLs;
	}
	public boolean isSimilarSearchEnabled(){
		return true;
	}
	public String processSummary(String summary){
		return summary;
	}

	public String processSource(SearchResult s){
		return s.getUstadz();
	}
	public void setCentralPanelLoading(){
		if(centralPanel != null)
			centralPanel.remove(resultPanel);
		if(pagingPanel != null)
			centralPanel.remove(pagingPanel);
		if(bottomSearch != null)
			centralPanel.remove(bottomSearch);
		//resultPanel = new HTMLPanel("<p align='left'> <br/>Loading...</p>");
		WebImages webImage = (WebImages) GWT.create(WebImages.class);
		Image loading = webImage.loader().createImage();
		resultPanel = new VerticalPanel();
		resultPanel.add(loading);
		VerticalPanel v = ((VerticalPanel)resultPanel);
		centralPanel.add(resultPanel);
		v.setCellWidth(loading, (2 *scrWidthResolution / 3)+"px");
		v.setCellHeight(loading, (2 *scrHeightResolution / 3)+"px");
		v.setCellHorizontalAlignment(loading, VerticalPanel.ALIGN_CENTER);
		v.setCellVerticalAlignment(loading, VerticalPanel.ALIGN_MIDDLE);
	}

	public void showErrorDialog(String errMsg){

		Window.alert(errMsg);
	}

	public void updateCentralPanel(SearchResult[] msg){
		if(msg != null && msg.length > 0){
			Window.enableScrolling(true);
		}
		if(resultPanel != null)
			centralPanel.remove(resultPanel);
		if(msg == null){
			resultPanel = new HTMLPanel("");
		}else{
			resultPanel = convertToHTML(msg);
		}
		centralPanel.add(resultPanel);
		if(pagingPanel != null){
			centralPanel.remove(pagingPanel);
			scrollToTop();
			if(bottomSearch != null)
				centralPanel.remove(bottomSearch);
			VerticalPanel v = (VerticalPanel) centralPanel;
			v.add(pagingPanel);
			v.setCellHorizontalAlignment(pagingPanel, VerticalPanel.ALIGN_CENTER);
			if(msg != null && msg.length > 7)
				v.add(bottomSearch);
		}
	}

	public static native void scrollToTop() /*-{
    	$wnd.scroll(0, 0);
	}-*/;
	public Panel createPagingPanel(int totalCount, String paramName,String paramValue){
		HorizontalPanel paging = new HorizontalPanel();
		int totalPg = (int) Math.ceil(totalCount / Constant.HIT_PER_PAGE);
		paging.setHeight("100%"); 
		paging.setWidth("20%");
		paging.setHorizontalAlignment(HorizontalPanel.ALIGN_CENTER);
		paging.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);

		class PagingHandler implements ClickHandler{
			private String paramName;
			private String sourceName;
			private int pageNum;
			private int qid; 
			private String keyword; 
			public PagingHandler(String text, String paramName, String paramValue, int pageNumber){
				this.keyword = text;
				this.paramName = paramName;
				pageNum = pageNumber;
				if(paramName.equalsIgnoreCase("questionid")){
					qid = Integer.parseInt(paramValue);
					sourceName = null;
				}
				else
					sourceName = paramValue;
			}
			@Override
			public void onClick(ClickEvent event) {
				setCentralPanelLoading();
				AppControlServiceAsync appService = getAppControlService();
				int start = (pageNum * Constant.HIT_PER_PAGE);
				if(paramName.equalsIgnoreCase("questionid")){
					appService.searchSimilarQuestion(keyword, qid, start, Constant.HIT_PER_PAGE, similarQuestionPagingCallBack);
					History.newItem("similarSearch&amp;"+keyword+"&amp;"+qid+"&amp;"+start);
				}else{
					if(sourceName == null){
						appService.searchKeyword(keyword, start, Constant.HIT_PER_PAGE, callback);
						History.newItem("search&amp;"+keyword+"&amp;"+start);
					}else{
						appService.searchKeyword(keyword,sourceName, start, Constant.HIT_PER_PAGE, callback);
						History.newItem("search&amp;"+keyword+"&amp;"+start+"&amp;"+sourceName);
					}
				}
			}
		}
		for(int i = 0; i < totalPg; i++){
			int label = i + 1;
			Anchor a = new Anchor(""+label,true);
			a.addClickHandler(new PagingHandler(searchBox.getText(),paramName,paramValue,i));
			paging.add(a);
		}

		return paging;
	}

	public void updatePagingPanel(int totalCount,String paramName,String paramValue){
		if(this.pagingPanel != null){
			centralPanel.remove(pagingPanel);
		}
		if(this.bottomSearch != null)
			centralPanel.remove(bottomSearch);

		pagingPanel = createPagingPanel(totalCount,paramName,paramValue);
		if(pagingPanel != null){
			centralPanel.add(pagingPanel);
			if(bottomSearch == null){
				bottomSearch = new FlexTable();
				bottomSearchBox = new TextBox();
				bottomSearchBox.setText(searchBox.getText());

				bottomSearchBox.addKeyDownHandler(new KeyButtonHandler());

				bottomButton = new Button("Cari");

				bottomButton.addClickHandler(new SearchButtonHandler());
				bottomSearch.setWidget(0, 0, bottomSearchBox);
				bottomSearch.setWidget(0, 1, bottomButton);
				bottomSearch.setWidget(1, 0, new HTML("&nbsp;"));
				bottomSearch.setWidget(1, 1, new HTML("&nbsp;"));
				bottomButton.setPixelSize(80, 25);
				bottomSearchBox.setWidth((getResultLsWidth() - 100) +"px");
			}
			VerticalPanel v = (VerticalPanel) centralPanel;
			v.setCellHorizontalAlignment(pagingPanel, VerticalPanel.ALIGN_CENTER);
			if(totalCount > 7)
				v.add(bottomSearch);
		}
	}
	public void updateLeftPanel(List<String> sources){
		removeLeftPanel();
		leftPanel = new VerticalPanel();


		class SourceSearchListener implements ClickHandler{

			private String keyword;
			private String sourceName;

			SourceSearchListener(String kword, String sname){
				keyword = kword;
				sourceName = sname;
			}
			@Override
			public void onClick(ClickEvent event) {
				setCentralPanelLoading();
				AppControlServiceAsync appService = getAppControlService();
				if(sourceName == null){
					appService.searchKeyword(keyword, callback);
					appService.getTotalCount(keyword, countCallBack);
					//History.newItem("search&amp;"+keyword);
				}
				else{
					appService.searchKeyword(keyword, sourceName, callback);
					SourceCountCallback countSourceCallback = new SourceCountCallback(sourceName);
					appService.getTotalCountForSource(keyword,sourceName, countSourceCallback);
					//History.newItem("search&amp;"+keyword+"&amp;"+sourceName+"&amp;"+0);
				}
			}
		}
		if(sources != null){
			Hyperlink all = new Hyperlink("semua sumber",true,"search&amp;"+searchBox.getText());
			all.addClickHandler(new SourceSearchListener(searchBox.getText(),null));
			leftPanel.add(all);
			for(String s : sources){
				Hyperlink h = new Hyperlink(s,true,"search&amp;"+searchBox.getText()+"&amp;"+s+"&amp;"+0);
				h.addClickHandler(new SourceSearchListener(searchBox.getText(),s));
				leftPanel.add(h);
			}
		}
		refreshLeftPanel();
	}
	public void refreshLeftPanel(){
		DockPanel dPanel = (DockPanel) panel;
		dPanel.add(leftPanel, DockPanel.WEST);
		leftPanel.add(new HTML("&nbsp;"));
		leftPanel.add(new HTML("&nbsp;"));
		leftPanel.add(new HTML("<iframe src=\"//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.ustadzmenjawab.com&amp;send=false&amp;layout=box_count&amp;width=55&amp;show_faces=true&amp;action=like&amp;colorscheme=light&amp;font&amp;height=90\" scrolling=\"no\" frameborder=\"0\" style=\"border:none; overflow:hidden; width:55px; height:90px;\" allowTransparency=\"true\"></iframe>"));
		leftPanel.add(new HTML("<iframe allowtransparency=\"true\" frameborder=\"0\" scrolling=\"no\" src=\"//platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fwww.ustadzmenjawab.com&amp;count=vertical&amp;lang=id&amp;text=search%20engine%20konsultasi%20syariah\" style=\"width:55px; height:62px;\"></iframe>"));
		dPanel.setCellWidth(leftPanel, LEFT_PANEL_WIDTH);

	}
	public void removeLeftPanel(){
		if(leftPanel != null && panel != null)
			panel.remove(leftPanel);
	}

	public static int getScreenWidth(){
		return Window.getClientWidth();
	}
	
	public static  int getScreenHeight(){
		return Window.getClientHeight();
	}
	
	/*public static native int getScreenWidth() /*-{ 
return $wnd.screen.width;
}-*/;


	/*public static native int getScreenHeight() /*-{ 
return $wnd.screen.height;
}-*/;


}
